package pl.edu.pw.perg.compinfodb.datamodel;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import pl.edu.pw.perg.compinfodb.entities.ElementType;
import pl.edu.pw.perg.compinfodb.entities.PhysicalElement;
import pl.edu.pw.perg.compinfodb.entities.VirtualElement;
import pl.edu.pw.perg.compinfodb.manager.IPhysicalElementManager;

// lista ma trzymac calosc danych.
// zawiera tez tymczasowa liste przefiltrowana.
// jesli tymczasowa lista sie zmieni, mozliwosc komitu zmian.
// Przy inicjalizacji opakowanie wszystkich elementow listy tymczasowej.

public class ElementDataList {

	private IPhysicalElementManager elementManager;
	private List<PhysicalElement> persistentList = new LinkedList<PhysicalElement>();
	private List<TableData> temporaryList = new ArrayList<TableData>();
	private List<VirtualElement> veFilter = new ArrayList<VirtualElement>();
	private ElementType typeFilter;
	private boolean typeChanged;
	private Map<Integer, String> stringFilters;
	private int markedRowId = -1;
	private TableData markedRowElement;
	Long dataId = -1L;
	private List<PhysicalElement> toSave = new LinkedList<PhysicalElement>();
	private boolean spare;
	private boolean all;

	public ElementDataList(IPhysicalElementManager elementManager) {
		this.elementManager = elementManager;
//		persistentList = elementManager.findAll();
//		search();
	}

	public TableData get(int index) {
		if (index >= temporaryList.size() || index < 0)
			return null;
		return temporaryList.get(index);
	}

	public void search(){
		search(null);
	}
	
	public void search(Map<String, String> filter) {
		toSave.clear();
		if(typeChanged){
			persistentList.clear();
			if (typeFilter != null)
				persistentList.addAll(elementManager.findElementsByType(typeFilter));
			else if(spare)
				persistentList.addAll(elementManager.findSpareElements());
			else if(all)
				persistentList.addAll(elementManager.findAll());
		}
		temporaryList.clear();

		for (PhysicalElement pe : persistentList) {
			TableData td = new TableData(pe);
			if(td.matchesFilter(filter)){
				temporaryList.add(td);
				if(dataId != null && pe.getVirtualElement() != null && pe.getVirtualElement().getId().equals(dataId))
					markedRowElement = td;
				
			}
		}
	}
	

	public int size() {
		return temporaryList.size();
	}

	public void setTypeFilter(ElementType typeFilter) {
		this.typeFilter = typeFilter;
	}

	public void setDataId(Long dataId) {
		this.dataId = dataId;
	}

	public int getMarkedRowId() {
		if(dataId == null)
			return -1;
		return temporaryList.indexOf(markedRowElement);
//		return markedRowId;
	}

	public void setTypeChanged(boolean typeChanged) {
		this.typeChanged = typeChanged;
	}

	public void save() {
		elementManager.saveAll(toSave);
		toSave.clear();
		
	}
	
	public void prepareToSave(TableData td){
		if(td.validate())
			toSave.add(td.getPe());
	}

	public void setValueAt(int rowIndex, String columnName, Object value) {
		TableData td = get(rowIndex);
		td.setValue(columnName, (String) value);
		prepareToSave(td);
		
	}

	public boolean isModified() {
		return toSave.size() > 0;
	}

	public void addNew() {
		PhysicalElement pe = new PhysicalElement();
		pe.setElementType(typeFilter);
		TableData td = new TableData(pe);
		temporaryList.add(td);
		prepareToSave(td);
		
	}

	public void setSpare(boolean isSpare) {
		spare = isSpare;
		
	}

	public void setAll(boolean isAll) {
		all = isAll;
		
	}

	public boolean isSpare() {
		return spare;
	}
	

}